package com.iwhalecloud.bss.kite.cucc.service.scene.operate;

import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneCommonService;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneMainOfferInstService;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneCommonService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.OfferInstDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.unpack.DeleteVo;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.validate.annotation.KiteNotBlank;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.operate.ICuccOperateSceneOfferInstService;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.service.scene.bo.CuccOperateSceneOfferInstBO;
import com.iwhalecloud.bss.kite.listener.handler.detail.impl.bo.OfferInstAttrsDealBO;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.util.InstTypeUtils;
import com.iwhalecloud.bss.kite.service.scene.bo.OperateSceneOfferInstBO;
import com.iwhalecloud.bss.kite.service.scene.bo.OperateSceneProdInstBO;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.order.base.consts.IKeyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class CuccOperateSceneOfferInstService implements ICuccOperateSceneOfferInstService {

    @Autowired
    private CuccOperateSceneOfferInstBO cuccOperateSceneOfferInstBO;

    @Autowired
    private IOperateSceneMainOfferInstService operateSceneMainOfferInstService;

    @Autowired
    private IQuerySceneAccessProdInstService querySceneAccessProdInstService;

    @Autowired
    private IQuerySceneCommonService querySceneCommonService;

    @Autowired
    private IOperateSceneCommonService operateSceneCommonService;

    @Autowired
    private IOperateSceneService operateSceneService;

    @Autowired
    private OfferInstAttrsDealBO offerInstAttrsDealBO;

    @Autowired
    private OperateSceneProdInstBO operateSceneProdInstBO;

    @Autowired
    private OperateSceneOfferInstBO operateSceneOfferInstBO;
    /**
     * 新增一个附加销售品实例
     *
     * @param sceneInstId
     * @param parOfferInstId
     * @param offerId
     * @param roleId
     * @param custId
     * @param staffId
     * @return
     */
    @Override
    public DataResult<KiteOfferInst> addMemOfferInst(String sceneInstId, String parOfferInstId, String offerId,
                                                     String roleId, String custId, String staffId) {
        return ErrorConsts.SUCCESS.getResult(cuccOperateSceneOfferInstBO.addMemOfferInst(sceneInstId, parOfferInstId, offerId, roleId, custId, staffId));
    }

    /***
     * 退订主套餐
     *
     * @param sceneInstId 场景实例ID
     * @param mainOfferInstId 主套餐实例ID
     * @param custId 客户标识
     * @param staffId 员工Id
     * @return
     */
    @Override
    @Validated
    public DataResult<Boolean> removeMemOfferInst(@KiteNotBlank String sceneInstId,
                                                   @KiteNotBlank String mainOfferInstId, @KiteNotBlank String custId, @KiteNotBlank String staffId) {
        return ErrorConsts.SUCCESS
            .getResult(cuccOperateSceneOfferInstBO.removeMemOfferInst(sceneInstId, mainOfferInstId, custId, staffId));
    }

    /**
     * 产品拆机和销售品解体操作
     * @param sceneInstId
     * @param custId
     * @param compInstId
     * @param offerType
     * @return
     */
    @Override
    public DataResult<DeleteVo> removeMemOffer(String sceneInstId, String custId, String compInstId,
                                            String offerType) {
        DeleteVo deleteVo = new DeleteVo();
        // 产品拆机
        if (IKeyValues.OFFER_KIND_0.equals(offerType)) {
            ProdInstDTO prodInst = querySceneAccessProdInstService
                .getSceneProdInstByProdInstId(sceneInstId, compInstId, custId).getResultObject();
            if (IKeyValues.ACTION_TYPE_D.equals(prodInst.getActionType())) {
                operateSceneService.rollbackByInst(sceneInstId, InstType.PROD_INST, compInstId);

            }
            else {
                operateSceneProdInstBO.dismantleProdInst(sceneInstId, custId, compInstId);
                operateSceneService.setTriggerInst(sceneInstId, InstType.PROD_INST, compInstId);
            }

            List<ProdInstDTO> prodInstDTOList = querySceneAccessProdInstService.listProdInsts(sceneInstId, custId).getResultObject();
            Set<ProdInstDTO> deletedProdInsts = prodInstDTOList.stream()
                .filter(t -> KiteStringUtils.equals(t.getActionType(), ActionType.D.name()))
                .collect(Collectors.toSet());
            processDeleted(deletedProdInsts, deleteVo);

            if (prodInstDTOList.stream().noneMatch(prodInstDTO -> IKeyValues.ACTION_TYPE_D.equals(prodInstDTO.getActionType()))) {
                return ErrorConsts.SUCCESS.getResult(this.refreshAttrs(sceneInstId, custId, true, deleteVo));
            }

        }

        String staffId = ContextUtil.getLoginStaffId() + "";
        if (LocalKeyConsts.OFFER_TYPE_MEMBER.equals(offerType)) {
            InstType instType = InstTypeUtils.getOfferInstType(offerType);
            OfferInstDTO offerInst = querySceneCommonService
                .getSceneOfferInstByOfferInstId(sceneInstId, compInstId, custId).getResultObject();
            if (IKeyValues.ACTION_TYPE_D.equals(offerInst.getActionType())) {
                operateSceneService.rollbackByInst(sceneInstId, instType, compInstId);
                return ErrorConsts.SUCCESS.getResult(this.refreshAttrs(sceneInstId, custId, false, deleteVo));
            }
            // 销售品解体
            this.removeMemOfferInst(sceneInstId, compInstId, custId, staffId);
            operateSceneService.setTriggerInst(sceneInstId, instType, compInstId);
        }
        else if (IKeyValues.OFFER_KIND_3.equals(offerType)) {
            //促销包销售品解体
            operateSceneMainOfferInstService.removeMainOfferInst(sceneInstId, compInstId, custId, staffId);
        }

        return ErrorConsts.SUCCESS.getResult(this.refreshAttrs(sceneInstId, custId, false, deleteVo));
    }

    /**
     * 返回给前端应该勾选的产品
     * @param deletedProdInsts
     * @param deleteVo
     */
    private void processDeleted(Set<ProdInstDTO> deletedProdInsts, DeleteVo deleteVo) {
        if (deletedProdInsts != null && !deletedProdInsts.isEmpty()) {
            Set<String> deleted = new HashSet<>();
            deletedProdInsts.forEach(d -> deleted.add(d.getProdInstId()));

            if (deleteVo.getDeletedProds() != null && !deleteVo.getDeletedProds().isEmpty()) {
                Set<String> deleteProdInstIds = deletedProdInsts.stream().map(ProdInstDTO::getProdInstId)
                    .collect(Collectors.toSet());
                if (deleteVo.getDeletedProds().containsAll(deleteProdInstIds)) { //有交集表示之前已经勾选，要删除
                    deleteVo.getDeletedProds().removeIf(sets -> {
                        return deletedProdInsts.stream()
                            .anyMatch(prods -> KiteStringUtils.equals(prods.getProdInstId(), sets));
                    });
                }
                else {
                    deleteVo.setDeletedProds(deleted);
                }
            }
            else {
                deleteVo.setDeletedProds(deleted);
            }
        }
        else {
            deleteVo.setDeletedProds(Collections.emptySet());
        }
    }

    private DeleteVo refreshAttrs(String sceneInstId, String custId, boolean isNull, DeleteVo deleteVo) {
        KiteAttr investTypeAttr = querySceneCommonService.getCommonAttr(sceneInstId, KeyConsts.BUSI_INVESTIGATE_TYPE)
            .getResultObject();
        KiteAttr investResultAttr = querySceneCommonService
            .getCommonAttr(sceneInstId, KeyConsts.BUSI_INVESTIGATE_RESULT).getResultObject();
        if (Objects.isNull(investTypeAttr) || Objects.isNull(investResultAttr)) {
            deleteVo.setInstAttrDTOS(Collections.emptyList());
            return deleteVo;
        }
        if (isNull) {
            investTypeAttr.setIsNull("T");
            investResultAttr.setIsNull("T");
        }
        else {
            investTypeAttr.setIsNull("F");
            investResultAttr.setIsNull("F");
        }
        operateSceneCommonService.setCommonAttr(sceneInstId, investTypeAttr);
        operateSceneCommonService.setCommonAttr(sceneInstId, investResultAttr);
        List<InstAttrDTO>  result = querySceneCommonService.listCommonAttrs(sceneInstId, custId).getResultObject();
        Collections.sort(result);
        deleteVo.setInstAttrDTOS(result);
        return deleteVo;
    }
}
